﻿using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

namespace System.Reflection
{
    /// <summary>
    /// 用于反射中使用的扩展方法
    /// </summary>
    [EditorBrowsable(EditorBrowsableState.Never)]
    public static class ReflectionExtensions
    {
        /// <summary>
        /// 判断指定的类型是否具有指定的接口
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static bool HasInterface<T>(this Type t)
        {
            return t != null && t.GetInterface(typeof(T).FullName) != null;
        }

        /// <summary>
        /// 获取所有静态属性
        /// </summary>
        /// <param name="type"></param>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public static PropertyInfo GetStaticProperty(this Type type, string propertyName)
        {
            return type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Static);
        }

        /// <summary>
        /// 获取所有的静态方法
        /// </summary>
        /// <param name="type"></param>
        /// <param name="methodName"></param>
        /// <returns></returns>
        public static MethodInfo GetStaticMethod(this Type type, string methodName)
        {
            return type.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static);
        }

        /// <summary>
        /// 获取对象的属性值
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="propertyName"></param>
        /// <param name="flags"></param>
        /// <returns></returns>
        public static object GetValue(this object obj, string propertyName, BindingFlags flags)
        {
            return obj.GetType().GetProperty(propertyName, flags).GetValue(obj, null);
        }

        /// <summary>
        /// 获取对象的属性值
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public static object GetValue(this object obj, string propertyName)
        {
            return obj.GetType().GetProperty(propertyName).GetValue(obj, null);
        }

        /// <summary>
        /// 设置对象的属性值
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="propertyName"></param>
        /// <param name="value"></param>
        public static void SetValue(this object obj, string propertyName, object value)
        {
            obj.GetType().GetProperty(propertyName).SetValue(obj, value, null);
        }

        /// <summary>
        /// 按照指定的接口过滤类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="src"></param>
        /// <returns></returns>
        public static IEnumerable<Type> FilterByInterface<T>(this IEnumerable<Type> src)
        {
            if (src == null)
                return null;

            return src.Where(x => x.HasInterface<T>());
        }
    }
}